﻿using ajayumi.develop.win32.Transport.Utils;
using ajayumi.develop.win32.Transport.WCF.Services;
using ajayumi.develop.win32.Transport.WCF.Services.DataContracts;
using System;
using System.IO;
using System.ServiceModel;

namespace ajayumi.develop.win32.Transport.Core
{
    /// <summary>
    /// 下载文件
    /// Author  : 黄乙冬
    /// Date    : 2011-08-30
    /// </summary>
    public class DownloadFile : TransFileBase
    {
        public string SaveDirectory { get; private set; }

        public Func<string> SaveDirectoryFunc
        {
            set
            {
                this.SaveDirectory = value.Invoke();
            }
        }

        protected Func<TransFileInfo, TransFileInfo> InvokeInitDownloadFile { get; private set; }

        protected Func<TransFileInfo, TransFileInfo> InvokeDownloadFile { get; private set; }

        public DownloadFile(string rootPath, string relativePath,
            Func<TransFileInfo, TransFileInfo> initDownloadFileFunc, Func<TransFileInfo, TransFileInfo> downloadFileFunc)
            : base(rootPath, relativePath, TransportAction.Download)
        {
            this.InvokeInitDownloadFile = initDownloadFileFunc;
            this.InvokeDownloadFile = downloadFileFunc;
        }

        protected override void BeginTransFileTask()
        {
            string path = Path.Combine(this.SaveDirectory, this.RelativePath);

            FileHelper.CreateDir(path);

            string fileName = Path.GetFileName(this.FilePath);
            long length = 0;
            FileInfo fileInfo = new FileInfo(path);
            if (fileInfo.Exists)
            {
                length = fileInfo.Length;
            }
            fileInfo = null;

            TransFileInfo tFileInfo = new TransFileInfo()
            {
                Name = fileName,
                RootDir = this.RootPath,
                RelativePath = this.RelativePath,
                Offset = length,
                TransportAction = this.TransportAction
            };
            int progressPercentage = 0;

            try
            {
                TransFileInfo transFileInfo = this.InvokeInitDownloadFile(tFileInfo);

                if (transFileInfo.Length > 0)
                {
                    progressPercentage = Convert.ToInt32(Convert.ToSingle(length) / Convert.ToSingle(transFileInfo.Length) * 100f);
                }
                this.OnTransReady(new TransReadyEventArgs(this.TransportAction, "", tFileInfo.RelativePath, transFileInfo.Length, progressPercentage));

                if (tFileInfo.Offset == transFileInfo.Length)
                {
                    this.OnTransCompleted(new TransCompletedEventArgs(this.TransportAction,
                        tFileInfo.RelativePath, path, DateTime.Now,
                        null, false, this));
                    return;
                }

                using (FileStream fileStream = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
                {
                    using (BinaryWriter writer = new BinaryWriter(fileStream))
                    {
                        while (transFileInfo.Offset != transFileInfo.Length)
                        {
                            TransFileInfo downloadInfo = this.InvokeDownloadFile(transFileInfo);
                            transFileInfo.Data = downloadInfo.Data;

                            long offset = transFileInfo.Offset;
                            writer.Seek((int)offset, SeekOrigin.Begin);
                            writer.Write(transFileInfo.Data);

                            transFileInfo.Offset = fileStream.Length;
                            transFileInfo.Data = null;

                            progressPercentage = Convert.ToInt32(Convert.ToSingle(transFileInfo.Offset) / Convert.ToSingle(transFileInfo.Length) * 100f);
                            this.OnTransProgressChanged(new TransProgressChangedEventArgs(this.TransportAction, tFileInfo.RelativePath, progressPercentage, this));
                            Console.WriteLine("{0} 客户端接收数据: {1}字节 {2}%", DateTime.Now, transFileInfo.Offset, progressPercentage);
                        }
                    } // end using writer
                } // end using filestream

                this.OnTransCompleted(new TransCompletedEventArgs(this.TransportAction,
                    tFileInfo.RelativePath, path, DateTime.Now,
                    null, false, this));

            }
            catch (FaultException ex)
            {
                this.OnTransCompleted(new TransCompletedEventArgs(this.TransportAction,
                    this.RelativePath, string.Empty, DateTime.Now,
                    ex, true, this));
            }
            catch (TimeoutException ex)
            {
                this.OnTransCompleted(new TransCompletedEventArgs(this.TransportAction,
                    this.RelativePath, string.Empty, DateTime.Now,
                    ex, true, this));
            }
            catch (Exception ex)
            {
                this.OnTransCompleted(new TransCompletedEventArgs(this.TransportAction,
                    this.RelativePath, string.Empty, DateTime.Now,
                    ex, true, this));
            }
        }


    }
}
